/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.rpc.api.service;

import io.iec.edp.caf.rpc.api.channel.RpcChanelAsynCallBack;
import io.iec.edp.caf.rpc.api.common.RpcChannelType;
import io.iec.edp.caf.rpc.api.support.Type;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.LinkedHashMap;

/**
 * This class is used to invoke rpc service in different way.
 */
public interface CAFRpcClient {

    /**
     * Caf rpc invoke
     * @param t return Type
     * @param serviceId service id
     * @param serviceUnitName su code
     * @param parameters params
     * @param channelType channelType(grpc,...)
     * @param context 上下文
     * @return t
     */
    <T> T invoke(Class<T> t, String serviceId, String serviceUnitName,
                 LinkedHashMap<String, Object> parameters, RpcChannelType channelType,HashMap<String, String> context);

    /**
     * invoke service (support Generics)
     *
     * @param t               return type
     * @param serviceId       service id
     * @param serviceUnitName msu code
     * @param parameters      service parameters
     * @param context         service context
     * @return
     */
    <T> T invoke(Type<T> t, String serviceId, String serviceUnitName,
                 LinkedHashMap<String, Object> parameters, RpcChannelType channelType, HashMap<String, String> context) throws IllegalAccessException, InstantiationException, IOException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException;


    /**
     * invoke service
     * @param t return type
     * @param serviceId service id
     * @param version rpc version
     * @param serviceUnitName msu code
     * @param parameters service parameters
     * @param context service context
     * @return T
     */
    <T> T invoke(Class<T> t, String serviceId, String version,String serviceUnitName,
                 LinkedHashMap<String, Object> parameters, RpcChannelType channelType, String filterType,HashMap<String, String> context);

    /**
     * invoke service (support Generics)
     *
     * @param t               return type
     * @param serviceId       service id
     * @param serviceUnitName msu code
     * @param parameters      service parameters
     * @param context         service context
     * @return
     */
    <T> T invoke(Type<T> t, String serviceId,String version, String serviceUnitName,
                 LinkedHashMap<String, Object> parameters, RpcChannelType channelType,String filterType, HashMap<String, String> context) throws IllegalAccessException, InstantiationException, IOException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException;


    /**
     * invoke service
     * @param serviceId service id
     * @param serviceUnitName msu code
     * @param parameters service parameters
     * @param context service context
     * @return
     */
    String invoke(String serviceId, String version,String serviceUnitName,
                  LinkedHashMap<String, Object> parameters, RpcChannelType channelType,String filterType,HashMap<String, String> context);


    /**
     * invoke service
     * @param serviceId service id
     * @param version   service version
     * @param serviceUnitName msu code
     * @param parameters service parameters
     * @param context service context
     * @return
     */
    InputStream invokeStream(String serviceId, String version, String serviceUnitName,
                              LinkedHashMap<String, Object> parameters, RpcChannelType channelType, String filterType, HashMap<String, String> context);

    void invokeStreamAsyn(String serviceId, String version, String serviceUnitName,
                      LinkedHashMap<String, Object> parameters, RpcChannelType channelType, String filterType, HashMap<String, String> context, RpcChanelAsynCallBack callBack);

    /**
     * invoke service
     * @param t         return type
     * @param serviceId service id
     * @param version   service version
     * @param serviceUnitName msu code
     * @param parameters service parameters
     * @param context service context
     * @return
     */
    <T> T invokeStream(Type<T> t,String serviceId,String version, String serviceUnitName,
                        LinkedHashMap<String, Object> parameters, RpcChannelType channelType,String filterType,HashMap<String, String> context);

    void setTimeout(Integer timeout);
}
